]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
notification: Use the same Source for showing system notifications
authorJulian Sparber <julian@sparber.net>
Fri, 2 Feb 2024 14:42:31 +0000 (15:42 +0100)
committerMarge Bot <marge-bot@gnome.org>
Tue, 6 Feb 2024 17:25:01 +0000 (17:25 +0000)
This drops all subclasses of `MessageTray.Source` that were used to
display system notifications. Now the `Source` returned from
`MessageTray.getSystemSource()` is used.
Ensure also that properties and methods that where set on the `Source`
are moved to the `Notification` object itself.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3156>

js/ui/components/autorunManager.js
js/ui/components/networkAgent.js
js/ui/main.js
js/ui/messageTray.js
js/ui/overview.js
js/ui/shellMountOperation.js
js/ui/status/network.js
js/ui/status/thunderbolt.js
tests/shell/basic.js

index 1ca58510f0cc82277c828b39e98931c513b764bd..d2b69d67e1302f027f7b9f6c4f093f8b17a8e6e5 100644 (file)
@@ -6,7 +6,6 @@ import GObject from 'gi://GObject';
 import St from 'gi://St';
 
 import * as GnomeSession from '../../misc/gnomeSession.js';
-import * as Main from '../main.js';
 import * as MessageTray from '../messageTray.js';
 
 Gio._promisify(Gio.Mount.prototype, 'guess_content_type');
@@ -165,7 +164,7 @@ class AutorunManager {
 class AutorunDispatcher {
     constructor(manager) {
         this._manager = manager;
-        this._sources = [];
+        this._notifications = new Map();
         this._settings = new Gio.Settings({schema_id: SETTINGS_SCHEMA});
     }
 
@@ -185,26 +184,16 @@ class AutorunDispatcher {
         return AutorunSetting.ASK;
     }
 
-    _getSourceForMount(mount) {
-        let filtered = this._sources.filter(source => source.mount === mount);
-
-        // we always make sure not to add two sources for the same
-        // mount in addMount(), so it's safe to assume filtered.length
-        // is always either 1 or 0.
-        if (filtered.length === 1)
-            return filtered[0];
-
-        return null;
-    }
-
-    _addSource(mount, apps) {
-        // if we already have a source showing for this
-        // mount, return
-        if (this._getSourceForMount(mount))
+    _addNotification(mount, apps) {
+        // Only show a new notification if there isn't already an existing one
+        if (this._notifications.has(mount))
             return;
 
-        // add a new source
-        this._sources.push(new AutorunSource(this._manager, mount, apps));
+        const source = MessageTray.getSystemSource();
+        const notification = new AutorunNotification(source, mount, apps);
+        notification.connect('destroy', () => this._notifications.delete(mount));
+        this._notifications.set(mount, notification);
+        source.showNotification(notification);
     }
 
     addMount(mount, apps, contentTypes) {
@@ -241,58 +230,29 @@ class AutorunDispatcher {
         // we fallback here also in case the settings did not specify 'ask',
         // but we failed launching the default app or the default file manager
         if (!success)
-            this._addSource(mount, apps);
+            this._addNotification(mount, apps);
     }
 
     removeMount(mount) {
-        let source = this._getSourceForMount(mount);
-
-        // if we aren't tracking this mount, don't do anything
-        if (!source)
-            return;
-
-        // destroy the notification source
-        source.destroy();
+        this._notifications.get(mount)?.destroy();
     }
 }
 
-const AutorunSource = GObject.registerClass(
-class AutorunSource extends MessageTray.Source {
-    constructor(manager, mount, apps) {
-        super({
-            title: mount.get_name(),
-            icon: mount.get_icon(),
-        });
-
-        this._manager = manager;
-        this.mount = mount;
-        this.apps = apps;
-
-        this._notification = new AutorunNotification(this._manager, this);
-
-        // add ourselves as a source, and popup the notification
-        Main.messageTray.add(this);
-        this.showNotification(this._notification);
-    }
-
-    _createPolicy() {
-        return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
-    }
-});
-
 const AutorunNotification = GObject.registerClass(
 class AutorunNotification extends MessageTray.Notification {
-    _init(manager, source) {
-        super._init(source, source.title);
+    constructor(source, mount, apps) {
+        super(source, mount.get_name());
 
-        this._manager = manager;
-        this._mount = source.mount;
+        this.gicon = mount.get_icon();
+
+        this._mount = mount;
+        this._apps = apps;
     }
 
     createBanner() {
         let banner = new MessageTray.NotificationBanner(this);
 
-        this.source.apps.forEach(app => {
+        this._apps.forEach(app => {
             let actor = this._buttonForApp(app);
 
             if (actor)
index 2a31b3037f978d523bbce78e5d70c57bfc3bdf90..9a8e98d341fe07f5303e53dd36300fe8058fa43d 100644 (file)
@@ -11,7 +11,6 @@ import St from 'gi://St';
 import * as Signals from '../../misc/signals.js';
 
 import * as Dialog from '../dialog.js';
-import * as Main from '../main.js';
 import * as MessageTray from '../messageTray.js';
 import * as ModalDialog from '../modalDialog.js';
 import * as ShellEntry from '../shellEntry.js';
@@ -740,12 +739,6 @@ class NetworkAgent {
     }
 
     _showNotification(requestId, connection, settingName, hints, flags) {
-        const source = new MessageTray.Source({
-            title: _('Network Manager'),
-            iconName: 'network-transmit-receive',
-        });
-        source.policy = new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
-
         let title, body;
 
         let connectionSetting = connection.get_setting_connection();
@@ -788,7 +781,9 @@ class NetworkAgent {
             return;
         }
 
-        let notification = new MessageTray.Notification(source, title, body);
+        const source = new MessageTray.getSystemSource();
+        const notification = new MessageTray.Notification(source, title, body);
+        notification.iconName = 'dialog-password-symbolic';
 
         notification.connect('activated', () => {
             notification.answered = true;
@@ -802,7 +797,6 @@ class NetworkAgent {
             delete this._notifications[requestId];
         });
 
-        Main.messageTray.add(source);
         source.showNotification(notification);
     }
 
index 23e36aba55867b31e62fe9b87049af6dc60c5594..5e991aa664861b99eba465bf630a1580c4620c6e 100644 (file)
@@ -274,8 +274,7 @@ async function _initializeUI() {
         if (lookingGlass?.isOpen)
             return; // assume user action
 
-        const source = new MessageTray.SystemNotificationSource();
-        messageTray.add(source);
+        const source = MessageTray.getSystemSource();
         const notification = new MessageTray.Notification(source,
             _('System was put in unsafe mode'),
             _('Apps now have unrestricted access'));
@@ -615,8 +614,7 @@ export function loadTheme() {
  * @param {string} details Additional information
  */
 export function notify(msg, details) {
-    let source = new MessageTray.SystemNotificationSource();
-    messageTray.add(source);
+    const source = MessageTray.getSystemSource();
     let notification = new MessageTray.Notification(source, msg, details);
     notification.setTransient(true);
     source.showNotification(notification);
index a069f16d4d15f584e6e3001d700f0ce1eaed0a47..2d21e98f479f22bf4bd0dd972587c1d2ec346bac 100644 (file)
@@ -1348,17 +1348,3 @@ export function getSystemSource() {
 
     return systemNotificationSource;
 }
-
-export const SystemNotificationSource = GObject.registerClass(
-class SystemNotificationSource extends Source {
-    constructor() {
-        super({
-            title: _('System Information'),
-            iconName: 'dialog-information-symbolic',
-        });
-    }
-
-    open() {
-        this.destroy();
-    }
-});
index 2b173a5e10a57d9948864ed957c1d73e6e8162dd..2d6c2a4ab57e27b9afc268ede23ed204f88b6bab 100644 (file)
@@ -28,41 +28,29 @@ const DND_WINDOW_SWITCH_TIMEOUT = 750;
 const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
 
 class ShellInfo {
-    constructor() {
-        this._source = null;
-    }
-
     setMessage(text, options) {
         options = Params.parse(options, {
             undoCallback: null,
             forFeedback: false,
         });
 
+        const source = MessageTray.getSystemSource();
         let undoCallback = options.undoCallback;
         let forFeedback = options.forFeedback;
 
-        if (this._source == null) {
-            this._source = new MessageTray.SystemNotificationSource();
-            this._source.connect('destroy', () => {
-                this._source = null;
-            });
-            Main.messageTray.add(this._source);
-        }
-
-        let notification = null;
-        if (this._source.notifications.length === 0) {
-            notification = new MessageTray.Notification(this._source, text, null);
-            notification.setTransient(true);
-            notification.setForFeedback(forFeedback);
+        if (!this._notification) {
+            this._notification = new MessageTray.Notification(source, text, null);
+            this._notification.setTransient(true);
+            this._notification.setForFeedback(forFeedback);
+            this._notification.connect('destroy', () => delete this._notification);
         } else {
-            notification = this._source.notifications[0];
-            notification.update(text, null, {clear: true});
+            this._notification.update(text, null, {clear: true});
         }
 
         if (undoCallback)
-            notification.addAction(_('Undo'), () => undoCallback());
+            this._notification.addAction(_('Undo'), () => undoCallback());
 
-        this._source.showNotification(notification);
+        source.showNotification(this._notification);
     }
 }
 
index d2ab867583902ef22a6c471a30fe776cdb2bf405..b02b65b6ceceff880df9cf9bee6a560f665a5273 100644 (file)
@@ -11,7 +11,6 @@ import St from 'gi://St';
 import * as Animation from './animation.js';
 import * as CheckBox from './checkBox.js';
 import * as Dialog from './dialog.js';
-import * as Main from './main.js';
 import * as MessageTray from './messageTray.js';
 import * as ModalDialog from './modalDialog.js';
 import * as Params from '../misc/params.js';
@@ -181,60 +180,43 @@ export class ShellMountOperation {
     }
 
     _onShowUnmountProgress(op, message, timeLeft, bytesLeft) {
-        if (!this._notifier)
-            this._notifier = new ShellUnmountNotifier();
-
         if (bytesLeft === 0)
-            this._notifier.done(message);
+            this._showUnmountNotificationDone(message);
         else
-            this._notifier.show(message);
+            this._showUnmountNotification(message);
     }
 
     borrowDialog() {
         this._dialog?.disconnectObject(this);
         return this._dialog;
     }
-}
-
-const ShellUnmountNotifier = GObject.registerClass(
-class ShellUnmountNotifier extends MessageTray.Source {
-    constructor() {
-        super({
-            iconName: 'media-removable',
-        });
 
-        this._notification = null;
-        Main.messageTray.add(this);
-    }
+    _createNotification(title, body) {
+        this._notification?.destroy();
 
-    show(message) {
-        let [header, text] = message.split('\n', 2);
+        const source = MessageTray.getSystemSource();
+        this._notification = new MessageTray.Notification(source, title, body);
 
-        if (!this._notification) {
-            this._notification = new MessageTray.Notification(this, header, text);
-            this._notification.setTransient(true);
-            this._notification.setUrgency(MessageTray.Urgency.CRITICAL);
-        } else {
-            this._notification.update(header, text);
-        }
-
-        this.showNotification(this._notification);
+        this._notification.setTransient(true);
+        this._notification.iconName = 'media-removable-symbolic';
+        this._notification.connect('destroy', () => delete this._notification);
+        source.showNotification(this._notification);
     }
 
-    done(message) {
-        if (this._notification) {
-            this._notification.destroy();
-            this._notification = null;
-        }
+    _showUnmountNotificationDone(message) {
+        if (message)
+            this._createNotification(message, null);
+    }
 
-        if (message) {
-            let notification = new MessageTray.Notification(this, message, null);
-            notification.setTransient(true);
+    _showUnmountNotification(message) {
+        const [title, body] = message.split('\n', 2);
 
-            this.showNotification(notification);
-        }
+        if (!this._notification)
+            this._createNotification(title, body);
+        else
+            this._notification.update(title, body);
     }
-});
+}
 
 const ShellMountQuestionDialog = GObject.registerClass({
     Signals: {'response': {param_types: [GObject.TYPE_INT]}},
index 4322c6761b8d77548b2bcec03897d7a255a9ec47..fee315cf5f483685b19fc3f91ec6b42beff96623 100644 (file)
@@ -2036,16 +2036,11 @@ class Indicator extends SystemIndicator {
     _onActivationFailed() {
         this._notification?.destroy();
 
-        const source = new MessageTray.Source({
-            title: _('Network Manager'),
-            iconName: 'network-error-symbolic',
-        });
-        source.policy =
-            new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
-
+        const source = MessageTray.getSystemSource();
         this._notification = new MessageTray.Notification(source,
             _('Connection failed'),
             _('Activation of network connection failed'));
+        this._notification.iconName = 'network-error-symbolic';
         this._notification.setUrgency(MessageTray.Urgency.HIGH);
         this._notification.setTransient(true);
         this._notification.connect('destroy',
index 51b6e4ba659ea56fbc0fbca856197aae6561b89e..f7cc64b8c2d380ec75adcc494463f6625dbf8b16 100644 (file)
@@ -236,7 +236,6 @@ class Indicator extends SystemIndicator {
         Main.sessionMode.connect('updated', this._sync.bind(this));
         this._sync();
 
-        this._source = null;
         this._perm = null;
         this._createPermission();
     }
@@ -254,27 +253,13 @@ class Indicator extends SystemIndicator {
         this._client.close();
     }
 
-    _ensureSource() {
-        if (!this._source) {
-            this._source = new MessageTray.Source({
-                title: _('Thunderbolt'),
-                iconName: 'thunderbolt-symbolic',
-            });
-            this._source.connect('destroy', () => (this._source = null));
-
-            Main.messageTray.add(this._source);
-        }
-
-        return this._source;
-    }
-
     _notify(title, body) {
         if (this._notification)
             this._notification.destroy();
 
-        let source = this._ensureSource();
-
+        const source = MessageTray.getSystemSource();
         this._notification = new MessageTray.Notification(source, title, body);
+        this._notification.iconName = 'thunderbolt-symbolic';
         this._notification.setUrgency(MessageTray.Urgency.HIGH);
         this._notification.connect('destroy', () => {
             this._notification = null;
index 831382932143a026625a8cd4bad0d4826b5853b6..e5bd8c18786ffc6cb38e761ef83c0b5e559c2d21 100644 (file)
@@ -50,8 +50,7 @@ export async function run() {
 
     // notification
     console.debug('Show notification message');
-    const source = new MessageTray.SystemNotificationSource();
-    Main.messageTray.add(source);
+    const source = new MessageTray.getSystemSource();
 
     Scripting.scriptEvent('notificationShowStart');
     source.connect('notification-show',